<?php
namespace script;
/**
 * 核心Db框架
 * @author sunhaoqiang(shqdev@163.com)
 * @time: 2019-08-25 16:38
*/
use config\Db as Conf;

class Db
{
    private $_host;
	private $_user;
	private $_pwd;
	private $_dbname;
	private $_port;
    private $_charset;
    private $_table;
    private $_where = "";
    private $_order = "";
    private $_group = "";
	private $pdo;
	private static $instance;       //Db 类的单例对象
    /**
     * 构造函数私有化后，不能再使用 new 外部调用，私有方法只能类内部使用。
     */
	private function __construct(Array $option = []){
        if (empty($option)) {
            $conf = new Conf();
            $option = ENV ? $conf['env']: $conf['dev'];
        }

        $this->_host = isset($option['host'])?$option['host']:'';
        $this->_user = isset($option['user'])?$option['user']:'';
        $this->_pass = isset($option['pass'])?$option['pass']:'';
        $this->_dbname = isset($option['dbname'])?$option['dbname']:'';
        $this->_port = isset($option['port'])?$option['port']:'';
        $this->_charset = isset($option['charset'])?$option['charset']:'';
        
        $dsn = "mysql:host=$this->_host;dbname=$this->_dbname;port=$this->_port;charset=$this->_charset";
        $this->pdo = new \PDO($dsn,$this->_user,$this->_pass);
    }
    /**
     * 防止克隆的方法:私有克隆方法
     */
	private function __clone(){
	}
	//提供一个静态的方法生成对象
	public static function connect(Array $option = []){
		//如何生成单例对象（只生成一个），先判断$pdo属性是否属于当前类的实例
		if(!self::$instance instanceof self){
			self::$instance = new self($option); 
		}
		return self::$instance;
    }
    /**
     * 修改数据库
     */
    public function database($dbname)
    {
        $this->_dbname = $dbname;
        $sql = "use `". $this->_dbname."`";
        $this->pdo->query($sql);
        return $this;
    }
    /**
     * 修改数据表
     */
    public function table($table)
    {
        $this->_table = $table;
        return $this;
    }
    /**
     * 插入一行数据
     */
    public function insert($data)
    {
        $sql = $this->analysisInsert($data);
        $result = $this->pdo->exec($sql);
        if (empty($result)) {
            throw new \Exception($this->pdo->errorInfo()[2], 1);
        }

        return $result;
    }
    /**
     * 插入多行数据
     */
    public function insertAll($data)
    {
        $data = array_map([$this, 'analysisInsert'], $data);
        $sql = implode(" ", array_values($data));

        echo date('Y-m-d H:i:s')."\n";
        $result = $this->pdo->exec($sql);
        echo date('Y-m-d H:i:s')."\n";
        if (empty($result)) {
            throw new \Exception($this->pdo->errorInfo()[2], 1);
        }
        return $result;
    }
    public function addAll($data)
    {
        
        if (empty($data)) {
            return false;
        }

        $data = array_map([$this, 'analysisAdd'], array_values($data));
        $fields = array_unique(array_column($data, 'field'));
        if (count($fields) == 1) {
            $fields = $fields[0];
        }else{
            throw new \Exception('字段不能为空');
        }

        $values = array_column($data, 'value');
        $values = implode(',', $values);
        $sql = "INSERT INTO `".$this->_table."` ($fields) VALUES $values";
        echo date('Y-m-d H:i:s')."\n";
        $result = $this->pdo->exec($sql);
        echo date('Y-m-d H:i:s')."\n";
        if (empty($result)) {
            throw new \Exception($this->pdo->errorInfo()[2], 1);
        }
        return $result;
    }
    public function analysisAdd($data)
    {
        if (!is_array($data)) {
            throw new \Exception('数据不能为空');
        }
        $field = array_keys($data);
        $field = array_map(function ($data)
                    {
                        return "`".$data."`";
                    }, $field);
        $field = implode(",", $field);

        $field_values = array_values($data);
        $field_values = array_map([$this->pdo,"quote"], $field_values);
        $value = implode(",", $field_values);

        $value = "(".$value.")";
        
        return [
            'value' => $value,
            'field' => $field
        ];
    }
    /**
     * 条件
     * 格式1（array）：[['id', '=', 1]]
     * 格式2（string）：'id = 1'
     */
    public function where($where)
    {
        if (is_string($where)) {
            $this->_where = $where;
            return $this;
        }
        if (is_array($where)) {
            
            $where = array_map(function ($data)
                        {
                            $data[0] = "`".$data[0]."`";
                            $data[2] = "'".$data[2]."'";
                            $data = implode(" ", $data);
                            return $data;
                        }, $where);

            $where =  implode(" AND ", $where);
            $this->_where = " WHERE ".$where;
            return $this;
        }
        throw new \Exception('where 格式不规则');
    }

    public function order($order, $rule = "ASC")
    {
        $this->_order = " ORDER BY `".$order."` ".$rule;
        return $this;
    }

    public function group($group)
    {
        $this->_order = " GROUP BY `".$group."`";
        return $this;
    }
    /**
     * 获取单条
     * 
     */
    public function get()
    {
        echo 'get';
    }
    /**
     * 获取单条数据的单个字段
     * 
     */
    public function getFeild()
    {
        echo 'get';
    }
    /**
     * 获取多条数据
     */
    public function select($field = "*")
    {
        // SELECT * FROM p_paper WHERE `short_title` = '人教新课标地理七年级上册第一章地球与地图检测练' ORDER BY `pid`
        $sql = "SELECT ".$field." FROM `".$this->_table."`".$this->_where.$this->_order.$this->_group;

       
        echo date('Y-m-d H:i:s')."\n";
        $pdo_statement = $this->pdo->query($sql);

        echo date('Y-m-d H:i:s')."\n";

        if($pdo_statement == false){
            //说明sql语句有误。输出错误信息
            throw new \Exception($this->pdo->errorInfo()[2], 1);
        }
        //执行到这里，说明sql语句没有问题
        $result = $pdo_statement->fetchAll(\PDO::FETCH_ASSOC);
        $pdo_statement->closeCursor();
        return $result;
    }
    public function update()
    {
        # code...
    }
    public function analysisInsert($data)
    {
        
        if (empty($data)) {
            throw new \Exception('数据不能为空');
        }

        $field = array_keys($data);
        $field = array_map(function ($data)
                    {
                        return "`".$data."`";
                    }, $field);
        $fields = implode(",", $field);

        $field_values = array_values($data);
        $field_values = array_map([$this->pdo,"quote"], $field_values);
        $values = implode(",", $field_values);

    
        if (empty($this->_table)) {
            throw new \Exception('数据表不能为空');
        }
        $sql = "INSERT INTO ".$this->_table." ($fields) VALUES ($values);";
        return $sql;
    }

    /**
     * 转换双引号和单引号
     */
    public function escape($string)
    {
        return htmlspecialchars($string, ENT_QUOTES);
    }
    
}

